package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.atguigu.tingshu.album.AlbumFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.user.strategy.ItemTypeStrategy;
import com.atguigu.tingshu.user.strategy.StrategyFactory;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;
    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private KafkaService kafkaService;

    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;

    @Autowired
    private AlbumFeignClient albumFeignClient;

    @Autowired
    private UserVipServiceMapper userVipServiceMapper;

    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;

    @Autowired
    private StrategyFactory strategyFactory;
    /**
     * 虚拟发货
     * /api/user/userInfo/savePaidRecord
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)  //TODO 分布式事务问题
    public void savePaidRecord(UserPaidRecordVo userPaidRecordVo) {
        ItemTypeStrategy strategy = strategyFactory.getStrategy(userPaidRecordVo.getItemType());
        strategy.savePaidRecord(userPaidRecordVo);


//        String itemType = userPaidRecordVo.getItemType();
//        if (itemType.equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)){
//            //专辑
//            //判断是否已经新增过记录
//            LambdaQueryWrapper<UserPaidAlbum> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//            lambdaQueryWrapper.eq(UserPaidAlbum::getOrderNo,userPaidRecordVo.getOrderNo());
//            Long aLong = userPaidAlbumMapper.selectCount(lambdaQueryWrapper);
//            if (aLong!=0){
//                return;
//            }
//            UserPaidAlbum userPaidAlbum = new UserPaidAlbum();
//            userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
//            userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
//            userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
//            userPaidAlbumMapper.insert(userPaidAlbum);
//        }
//        else if(itemType.equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)) {
//            //声音
//            //判断是否已经新增过记录
//            LambdaQueryWrapper<UserPaidTrack> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//            lambdaQueryWrapper.eq(UserPaidTrack::getOrderNo,userPaidRecordVo.getOrderNo());
//            Long aLong = userPaidTrackMapper.selectCount(lambdaQueryWrapper);
//            if (aLong>0){
//                return;
//            }
//            //根据声音id查询声音信息获取里面的专辑id
//            TrackInfo trackInfo = albumFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0)).getData();
//
//            for (Long aLong1 : userPaidRecordVo.getItemIdList()) {
//                UserPaidTrack userPaidTrack = new UserPaidTrack();
//                userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
//                userPaidTrack.setUserId(userPaidRecordVo.getUserId());
//                userPaidTrack.setAlbumId(trackInfo.getAlbumId());
//                userPaidTrack.setTrackId(aLong1);
//                userPaidTrackMapper.insert(userPaidTrack);
//            }
//
//        }
//        else if (itemType.equals(SystemConstant.ORDER_ITEM_TYPE_VIP)){
//            //vip
//            //判断是否已经新增过记录
//            LambdaQueryWrapper<UserVipService> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//            lambdaQueryWrapper.eq(UserVipService::getOrderNo,userPaidRecordVo.getOrderNo());
//            Long aLong = userVipServiceMapper.selectCount(lambdaQueryWrapper);
//            if (aLong>0){
//                return;
//            }
//            //添加vip服务购买记录
//            UserVipService userVipService = new UserVipService();
//            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
//            userVipService.setUserId(userPaidRecordVo.getUserId());
//            //查看用户信息
//            UserInfo userInfo = userInfoMapper.selectById(userPaidRecordVo.getUserId());
//            //获取会员到期时间
//            Date vipExpireTime = userInfo.getVipExpireTime();
//            Integer isVip = userInfo.getIsVip();
//            //查看充值的会员类型
//            VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(userPaidRecordVo.getItemIdList().get(0));
//            //获取这个类型的月份
//            Integer serviceMonth = vipServiceConfig.getServiceMonth();
//            //判断是否还是会员
//           if (isVip==1 && vipExpireTime.after(new Date()) ){
//                //如果是会员,开始时间是原本的结束时间
//               userVipService.setStartTime(vipExpireTime);
//               //过期时间为原本到期时间加上服务月份
//               userVipService.setExpireTime(DateUtil.offsetMonth(vipExpireTime, serviceMonth));
//           }else {
//               //不是会员开始时间为现在
//               userVipService.setStartTime(new Date());
//               //不是会员就是现在加上服务月份
//               userVipService.setExpireTime(DateUtil.offsetMonth(new Date(), serviceMonth));
//           }
//            userVipServiceMapper.insert(userVipService);
//           //更新用户会员状态
//            userInfo.setIsVip(1);
//            userInfo.setVipExpireTime(userVipService.getExpireTime());
//            userInfo.setUpdateTime(new Date());
//            userInfoMapper.updateById(userInfo);
//        }


    }

    /**
     * 根据专辑id+用户ID获取用户已购买声音id列表
     * /api/user/userInfo/findUserPaidTrackList/{albumId}
     * @param albumId
     * @return
     */
    @Override
    public List<Long> findUserPaidTrackList(Long albumId, Long userId) {
        LambdaQueryWrapper<UserPaidTrack> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserPaidTrack::getAlbumId,albumId);
        lambdaQueryWrapper.eq(UserPaidTrack::getUserId,userId);
        List<UserPaidTrack> userPaidTracks = userPaidTrackMapper.selectList(lambdaQueryWrapper);
        List<Long> trackIdList = userPaidTracks.stream().map(userPaidTrack -> userPaidTrack.getId()).collect(Collectors.toList());
        return trackIdList;
    }



    /**
     * 判断用户是否购买过指定专辑
     * /api/user/userInfo/isPaidAlbum/{albumId}
     * @param albumId
     * @return
     */
    @Override
    public Boolean isPaidAlbum(Long albumId, Long userId) {
        LambdaQueryWrapper<UserPaidAlbum> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserPaidAlbum::getAlbumId,albumId);
        lambdaQueryWrapper.eq(UserPaidAlbum::getUserId,userId);
        Long aLong = userPaidAlbumMapper.selectCount(lambdaQueryWrapper);
        //有为真，没有为假
        return aLong>0;
    }


    /**
     * 获取用户声音列表付费情况
     * /api/user/userInfo/userIsPaidTrack/{userId}/{albumId}
     */
    @Override
    public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needChackTrackIdList) {
        //创建map
        Map<Long, Integer> map = new HashMap<>();
        //查询专辑是否购买
        LambdaQueryWrapper<UserPaidAlbum> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserPaidAlbum::getUserId,userId);
        lambdaQueryWrapper.eq(UserPaidAlbum::getAlbumId,albumId);
        Long aLong = userPaidAlbumMapper.selectCount(lambdaQueryWrapper);
        //如果购买了，所有的id都是1
        if (aLong.intValue()>0){
            for (Long aLong1 : needChackTrackIdList) {
                map.put(aLong1,1);
            }
            return map;
        }
        //根据声音列表查询列表中包含的声音是否购买
        QueryWrapper<UserPaidTrack> trackQueryWrapper=new QueryWrapper<>();
        trackQueryWrapper.eq("user_id",userId);
        trackQueryWrapper.in("track_id",needChackTrackIdList);
        List<UserPaidTrack> userPaidTracks = userPaidTrackMapper.selectList(trackQueryWrapper);

//        LambdaQueryWrapper<UserPaidTrack> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
//        lambdaQueryWrapper1.eq(UserPaidTrack::getUserId,userId);
//        lambdaQueryWrapper1.in(UserPaidTrack::getTrackId,needChackTrackIdList);
//        List<UserPaidTrack> userPaidTracks = userPaidTrackMapper.selectList(lambdaQueryWrapper1);
        //没有查到说明用户没有购买，设置为0
        if (CollectionUtil.isEmpty(userPaidTracks)){
            for (Long aLong1 : needChackTrackIdList) {
                map.put(aLong1,0);
            }
            return map;
        }
        //处理为只有id的集合
        List<Long> collect = userPaidTracks.stream().map(userPaidTrack -> userPaidTrack.getTrackId()).collect(Collectors.toList());
        //如果查到了，吧查到的id设置为1
        for (Long aLong1 : needChackTrackIdList) {
            //判断collect中是否包含aLong1，如果包含说明购买了
            if (collect.contains(aLong1)){
                map.put(aLong1,1);
            }else {
                map.put(aLong1,0);
            }
        }
        return map;
    }



    /**
     * 微信登录
     * @param code
     * @return
     */
    @Override
    public Map<String, String> wxLogin(String code) {
        Map<String,String> map = null;
        try {
            map = new HashMap<>();

            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            //不等于空说明授权成功
            if (sessionInfo!=null){

                String openid = sessionInfo.getOpenid();

                LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(UserInfo::getWxOpenId,openid);

                UserInfo userInfo = userInfoMapper.selectOne(lambdaQueryWrapper);
                if (userInfo == null){
                    //进入这里说明是注册，要给初始值
                    userInfo = new UserInfo();
                    userInfo.setWxOpenId(openid);
                    userInfo.setNickname("游客：" + IdUtil.fastSimpleUUID());
                    userInfo.setAvatarUrl("https://tse2-mm.cn.bing.net/th/id/OIP-C.uMf5AX3a6yYpIhpEkyDxiQAAAA?rs=1&pid=ImgDetMain");
                    userInfo.setIsVip(0);
                    //存入数据库
                    userInfoMapper.insert(userInfo);
                    //初始化账户
                    kafkaService.sendMessage(KafkaConstant.QUEUE_USER_PAY_RECORD,userInfo.getId().toString());

                }
                //生成token
                String token = IdUtil.getSnowflakeNextIdStr();
                String redisToken = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
                map.put("token",token);
                //存入redis
                UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
                redisTemplate.opsForValue().set(redisToken,userInfoVo,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
            }
        } catch (WxErrorException e) {
            log.error("[用户服务]微信登录异常：{}", e);
            throw new RuntimeException(e);
        }
        return map;
    }

    @Override
    public UserInfoVo getUserInfo(Long userId) {
        UserInfo userInfo = userInfoMapper.selectById(userId);
        UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class);
        return userInfoVo;
    }

    @Override
    public void updateUser(UserInfoVo userInfoVo) {
        UserInfo userInfo = BeanUtil.copyProperties(userInfoVo,UserInfo.class);
        userInfoMapper.updateById(userInfo);
    }




}
